﻿using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using Microsoft.TeamFoundation.Framework.Client;
using VisualWip.Core;
using VisualWip.Core.Interfaces;
using VisualWip.TFS2010Common;

namespace VisualWip.TFS2010PersistanceProvider
{
    [Export(typeof (IPersistanceProvider))]
    public class TFS2010PersistanceProvider : IPersistanceProvider
    {
        private readonly TFSPropertyServiceHelper _propertyServiceHelper;
        private readonly IPersistanceTreeSerializer _serializer;

        [ImportingConstructor]
        public TFS2010PersistanceProvider(IPersistanceTreeSerializer serializer,
                                          TFSPropertyServiceHelper propertyServiceHelper)
        {
            _serializer = serializer;
            _propertyServiceHelper = propertyServiceHelper;
        }

        #region IPersistanceProvider Members

        public string Name
        {
            get { return "Team Foundation Server 2010 persistance provider"; }
        }

        public bool IsSettingsPathSupported(ISettingsPath settingsPath)
        {
            return settingsPath is TFSConnectionSettingsPath;
        }

        public void Persist(ISettingsPath settingsPath, PersistenceTree persistenceTree)
        {
            IPropertyService propertyService =
                _propertyServiceHelper.GetPropertyService(GetConnection(settingsPath,"Select project to save settings in"));

            using (var memoryStream = new MemoryStream())
            {
                _serializer.Save(memoryStream, persistenceTree);

                propertyService.SetProperty(_propertyServiceHelper.ArtifactSpec, settingsPath.Path,
                                            memoryStream.ToArray());
            }
        }


        public PersistenceTree Load(ISettingsPath settingsPath)
        {
            TfsConnection connection = GetConnection(settingsPath, "Select project to load settings from");
            IPropertyService propertyService = _propertyServiceHelper.GetPropertyService(connection);

            ArtifactPropertyValue[] props = propertyService.GetProperties(_propertyServiceHelper.ArtifactSpec,
                                                                          new[] {settingsPath.Path});

            if (props.Length < 1)
            {
                throw new KeyNotFoundException(
                    string.Format("Key {0}{1} was not found in property store for project {2}",
                                  TFSPropertyServiceHelper.VisualWipSettingsMoniker,
                                  settingsPath.Path, connection.ProjectName));
            }

            var byteArray = (byte[]) props[0].PropertyValues[0].Value;
            using (var memoryStream = new MemoryStream(byteArray))
            {
                return _serializer.Load(memoryStream);
            }
        }

        public PersistenceTree LoadFromPathString(string pathString)
        {
            return Load(new TFSConnectionSettingsPath {Path = pathString});
        }

        public IPathSelector PathSelector
        {
            get { return new TFS2010PathSelector(_propertyServiceHelper); }
        }

        #endregion

        public TfsConnection GetConnection(ISettingsPath settingsPath, string dialogText)
        {
            var tfsConnectionSettingsPath = settingsPath as TFSConnectionSettingsPath;
            TfsConnection connection = tfsConnectionSettingsPath == null
                                           ? new TfsConnection()
                                           : tfsConnectionSettingsPath.Connection;
            connection.Connect(dialogText);
            return connection;
        }
    }
}